import http from '@/utils/http'
import { useAuthStore } from '@/stores/auth'
import { fetchEventSource } from '@microsoft/fetch-event-source'
import { xSessionId } from '@/utils/utils'

class FatalError extends Error {}

const unlimited = {
  list: (page = 1, pageSize = 50) => http.get(`/chat/unlimited?page=${page}&pageSize=${pageSize}`),

  read: (id) => http.get(`/chat/unlimited/${id}`),

  create: (data) => http.post(`/chat/unlimited`, data),

  update: (id, data) => http.put(`/chat/unlimited/${id}`, data),

  delete: (id) => http.delete(`/chat/unlimited/${id}`),
}

const category = {
  list: (type) => http.get(`/chat/${type}/categories`),
}

const role = {
  list: (type, params = {}) => {
    const defaultParams = {
      page: 1,
      pageSize: 50,
    }
    params = Object.assign(defaultParams, params)
    return http.get(`/chat/${type}?` + new URLSearchParams(params).toString())
  },

  read: (id, type) => http.get(`/chat/${type}/${id}`),

  favorite: {
    add: (id, type) => http.post(`/chat/${type}/${id}/favorite`),
    delete: (id, type) => http.delete(`/chat/${type}/${id}/favorite`),
    toggle: (obj) =>
      obj.favorite ? role.favorite.delete(obj.id, obj.type) : role.favorite.add(obj.id, obj.type),
  },
}

const channel = {
  list: () => http.get('/chat/index/channels'),
}

const message = {
  histories: (objectType, objectId, options = {}) => {
    const urlParams = new URLSearchParams({
      object_type: objectType,
      object_id: objectId,
      channel_id: options?.channelId ?? 0,
      last_id: options?.lastId ?? 0,
      pageSize: options?.pageSize ?? 10,
    })
    return http.get('/chat/message/history?' + urlParams.toString())
  },

  clearContext: (messageId) => http.post(`/chat/message/${messageId}/clearContext`),

  delete: (messageId) => http.delete(`/chat/message/${messageId}`),

  deleteAll: (objectType, objectId, channelId) =>
    http.delete(
      `/chat/message/deleteAll?object_type=${objectType}&object_id=${objectId}&channel_id=${channelId}`
    ),

  send: (objectType, objectId, channelId, promptText, options) => {
    const defaultOptions = {
      isFirst: false,
    }
    options = Object.assign(defaultOptions, options)
    const values = {
      object_type: objectType,
      object_id: objectId,
      channel_id: channelId,
      prompt_text: promptText,
      is_first: options.isFirst ? 1 : 0,
    }
    return http.post('/chat/message/send', values)
  },

  receive: (receiveId) => http.get(`/chat/message/receive?id=${receiveId}`),

  streamReceive: (receiveId, onReceive, onFinish, ctrl) => {
    const url = http.defaults.baseURL + `/chat/message/receiveStream?id=${receiveId}`
    const authStore = useAuthStore()
    return fetchEventSource(url, {
      headers: {
        'Content-Type': 'application/json',
        Authorization: 'Bearer ' + authStore.token,
        'X-Session-Id': xSessionId.get(),
      },
      openWhenHidden: true,
      signal: ctrl.signal,
      async onopen(response) {
        console.log('onopen')
        if (response.ok) {
          return //一切正常
        } else if (response.status == 401) {
          authStore.clear()
          throw new FatalError('401')
        } else {
          throw new FatalError()
        }
      },
      onmessage: (msg) => {
        if (msg?.data.length) {
          const data = JSON.parse(msg.data)
          onReceive(data)
        }
      },
      onclose: onFinish,
      onerror: (err) => {
        throw err
      },
    })
  },

  cancel: (receiveId) => http.post(`/chat/message/${receiveId}/cancel`),
}

export default {
  unlimited,
  category,
  role,
  channel,
  message,
}
